#include "e2d/ui/Inst.h"
#include "sysx/System.h"

#include <thread>
#include <chrono>

using namespace fxcc::platform;
using namespace fxcc::graph;
using namespace fxcc::graph::opengl3;
using namespace fxcc::imgui::graph::opengl3;
using BaseApp = fxcc::graph::opengl3::GlfwApp;

#undef main

extern "C" {
    __declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001;
}

struct SimpleApp : public BaseApp
{
public:

    std::shared_ptr<e2d::Inst> m_Inst;

    e2d::Timer m_e2dTimer;

    glm::vec4 color;

    SimpleApp(const fxcc::platform::common::App::Desc &desc) : BaseApp(desc), color(1.0)
    {
    }
    bool Init() override
    {
        if (!BaseApp::Init())
        {
            return false;
        }

        if (!InitResources())
        {
            return false;
        }

        return true;
    };
    fxcc::yml::Serializer serializer;

    bool InitResources()
    {
        // Init Scene
        m_Inst = std::make_shared<e2d::Inst>();

        std::string filePath = sysx::System::OpenDialog("Open Scene ");
        
        bool flag = serializer.DecodePath<e2d::Inst>(filePath, *m_Inst);

        if (!flag) {
         
            return false;
        }

        m_Inst->OnLoad();

        m_Inst->OnStart();

        m_e2dTimer.Start();

        return true;
    };

    void OnDestroy() override
    {
        m_Inst->OnDestory();
        BaseApp::OnDestroy();
    }

    void OnFrameRender() override
    {
        m_Inst->OnRender();
        m_Inst->OnRenderRuntime();

    };

    void OnClose() override
    {
        m_Inst->OnDestory();
        BaseApp::OnClose();
    }
    void OnFramebuffersize(int w, int h) override
    {
        opengl3::GlfwApp::OnFramebuffersize(w, h);
     
        if(m_Inst)
            m_Inst->OnFramebuffersize({ w,h });
    }

    void OnUpdate() override
    {
        opengl3::GlfwApp::OnUpdate();

        m_e2dTimer.Tick();
        m_Inst->SetInput(&m_Input);
        m_Inst->SetTimer(&m_e2dTimer);

        m_Inst->OnUpdate();
        m_Inst->OnUpdateRuntime();

    }
};

int main()
{
    ztclog::pushFunction([](const ztclog::Line &line)
                         {
		if (line.m_Type != ztclog::Line::Type::_line_debug_)
		{
			std::cout << line.m_Text << std::endl;
		} });

    using _App = SimpleApp;
    using _Desc = fxcc::platform::common::App::Desc;

    _Desc desc;
    desc.m_Pos = glm::ivec2(100, 100);
    desc.m_Size = glm::ivec2(900, 600);
    desc.m_ScaleFactor = 1.0f;

    desc.m_Title = "e2d game Launcher";
    std::shared_ptr<_App> _app = std::make_shared<_App>(desc);
    return _app->Run();
};
